package com.byx.chatclient.utils;

import com.byx.chatclient.entity.Result;
import com.byx.chatclient.entity.ResultCode;
import com.google.gson.Gson;
import com.google.gson.JsonDeserializationContext;
import com.google.gson.JsonDeserializer;
import com.google.gson.JsonElement;
import com.google.gson.JsonParseException;
import com.google.gson.JsonPrimitive;
import com.google.gson.JsonSerializationContext;
import com.google.gson.JsonSerializer;

import java.lang.reflect.Type;

/**
 * EnumSerializer
 *
 * @author Superb
 * @date 2021/3/31 23:03
 */
public class EnumSerializer implements JsonSerializer<ResultCode>, JsonDeserializer<Result> {
    /**
     * Gson invokes this call-back method during deserialization when it encounters a field of the
     * specified type.
     * <p>In the implementation of this call-back method, you should consider invoking
     * {@link JsonDeserializationContext#deserialize(JsonElement, Type)} method to create objects
     * for any non-trivial field of the returned object. However, you should never invoke it on the
     * the same type passing {@code json} since that will cause an infinite loop (Gson will call your
     * call-back method again).
     *
     * @param json    The Json data being deserialized
     * @param typeOfT The type of the Object to deserialize to
     * @param context
     * @return a deserialized object of the specified type typeOfT which is a subclass of {@code T}
     * @throws JsonParseException if json is not in the expected format of {@code typeofT}
     */
    @Override
    public Result deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {

        return new Gson().fromJson(json,typeOfT);
//        Result result = new Result();
//        if(json.isJsonObject()){
//            JsonObject jsonObject = json.getAsJsonObject();
//            int code = jsonObject.get("code").getAsInt();
//            boolean find = false;
//            for(ResultCode resultCode : ResultCode.values()){
//                if(resultCode.getCode().equals(code)){
//                    result.setCode(resultCode.getCode());
//                    find = true;
//                }
//            }
//            if (!find){
//                result.setCode(ResultCode.UNDEFINED.getCode());
//            }
//            result.setData(jsonObject.get("data"));
//        }
//        return result;
    }

    /**
     * Gson invokes this call-back method during serialization when it encounters a field of the
     * specified type.
     *
     * <p>In the implementation of this call-back method, you should consider invoking
     * {@link JsonSerializationContext#serialize(Object, Type)} method to create JsonElements for any
     * non-trivial field of the {@code src} object. However, you should never invoke it on the
     * {@code src} object itself since that will cause an infinite loop (Gson will call your
     * call-back method again).</p>
     *
     * @param src       the object that needs to be converted to Json.
     * @param typeOfSrc the actual type (fully genericized version) of the source object.
     * @param context
     * @return a JsonElement corresponding to the specified object.
     */
    @Override
    public JsonElement serialize(ResultCode src, Type typeOfSrc, JsonSerializationContext context) {
        return new JsonPrimitive(src.code());
    }
}
